package pr.lanmu.config.util;

import lombok.Data;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

@Data
public class ValidBase {
    public final static String TYPE_STRING = "string";
    public final static String TYPE_NUMBER = "number";
    public final static String TYPE_BOOLEAN = "boolean";

    private Integer min;
    private Integer max;
    private String type;
    private Boolean required;
    private List<String> regular;

    public void valid(Object param, Object paramName, String level, List<String> errors) {
        String type = getType();
        Boolean required = getRequired();
        this.required = required != null && required;

        if (Objects.nonNull(type) && type.equals(TYPE_STRING) || Objects.nonNull(type) && type.equals(TYPE_NUMBER) || Objects.nonNull(type) && type.equals(TYPE_BOOLEAN)) {
            dealField(param, paramName, level, errors);
        } else {
            errors.add(String.format("参数：%s | 位置：%s | 错误：没有指定类型或类型不存在", paramName, level));
        }
    }

    private void dealField(Object param, Object paramName, String level, List<String> errors) {
        if (Objects.isNull(param)) {
            if (required) errors.add(String.format("参数：%s | 位置：%s | 错误：不能为空", paramName, level));
        } else {
            //类型校验
            if (TYPE_STRING.equals(type)) {
                if (!(param instanceof String)) {
                    errors.add(String.format("参数：%s | 位置：%s | 错误：类型不是string", paramName, level));
                }
                String paramStr = param.toString();
                int length = paramStr.length();
                if (Objects.nonNull(min) && length < min)
                    errors.add(String.format("参数：%s | 位置：%s | 错误：长度不能小于%s", paramName, level, min));
                if (Objects.nonNull(max) && length > max)
                    errors.add(String.format("参数：%s | 位置：%s | 错误：长度不能大于%s", paramName, level, max));
            }
            if (TYPE_NUMBER.equals(type)) {
                if (!(param instanceof Number)) {
                    errors.add(String.format("参数：%s | 位置：%s | 错误：类型不是number", paramName, level));
                }
                String paramStr = param.toString();
                BigDecimal bigDecimal = new BigDecimal(paramStr);
                //bigDecimal和min比较
                if (Objects.nonNull(min) && bigDecimal.compareTo(new BigDecimal(min)) < 0)
                    errors.add(String.format("参数：%s | 位置：%s | 错误：不能小于%s", paramName, level, min));
                //bigDecimal和max比较
                if (Objects.nonNull(max) && bigDecimal.compareTo(new BigDecimal(max)) > 0)
                    errors.add(String.format("参数：%s | 位置：%s | 错误：不能大于%s", paramName, level, max));
            }
            if (TYPE_BOOLEAN.equals(type)) {
                if (!(param instanceof Boolean)) {
                    errors.add(String.format("参数：%s | 位置：%s | 错误：类型不是boolean", paramName, level));
                }
            }
            String paramStr = param.toString();
            if (Objects.nonNull(regular) && regular.size() > 0) {
                regular.parallelStream()
                        .forEach(r -> {
                            if (!paramStr.matches(r))
                                errors.add(String.format("参数：%s | 位置：%s | 错误：不符合正则表达式%s", paramName, level, r));
                        });
            }
        }
    }
}
